package main

import (
	"fmt"
)

func main() {
	//创建一个切片
	//创建1,类似数组直接写入
	arr := []int{9, 8, 7, 6, 5, 4, 3, 2, 1}
	//创建2,make([]type,len,cap)
	slice := make([]int, 16, 32)

	//切片中,最后一个数字不切取
	fmt.Println("arr[2:7]=", arr[2:7]) //7, 6, 5, 4, 3
	fmt.Println("arr[:7]=", arr[:7])   //9, 8, 7, 6, 5, 4, 3
	fmt.Println("arr[2:]=", arr[2:])   //7, 6, 5, 4, 3, 2, 1
	fmt.Println("arr[:]=", arr[:])     //9, 8, 7, 6, 5, 4, 3, 2, 1

	//执行赋值函数
	fmt.Println("原来的数组", arr)
	sss(arr[:], 11111)
	fmt.Println("切片1:", arr[:])
	fmt.Println("改变的数组1", arr)

	//切片再切
	s1 := arr[2:7] //7, 6, 5, 4, 3
	s2 := s1[:3]   //7, 6, 5
	fmt.Println("切片s2:", s2)

	//切片多取(扩展cap,虽然超出了s2的范围,但是s2还是保留有cap,所以对应的位置是arr)
	s3 := s2[3:] //4, 3, 2
	fmt.Println("切片s3:", s3)
	fmt.Printf("s3=%d, len(s3)=%d, cap(s3)=%d\n", s3, len(s3), cap(s3))

	s4 := s3[3:4] //1
	fmt.Println("切片s4", s4)

	s5 := s3[3:4] //报错,超出cap的位置,所以报错
	fmt.Println("切片s5", s5)

	//元素添加 s2 7, 6, 5(添加的元素超过原cap,系统会分配更大的底层数组)
	s6 := append(s2, 10, 11, 12, 13)     //未超过,所以arr会被他的赋值改变
	s7 := append(s2, 20, 21, 22, 23, 24) //超过,系统会重新分配数组给他
	fmt.Println("切片s6,s7", s6, s7)       //	[7 6 5 10 11 12 13] [7 6 5 20 21 22 23 24]
	fmt.Println("改变的数组", arr)            //	[11111 8 7 6 5 10 11 12 13]

	//slice的复制 (copy(a,b) 把b复制给a)
	copy_slice := make([]int, 20)
	copy(copy_slice, arr)
	fmt.Println("copy:", copy_slice) //[11111 8 7 6 5 10 11 12 13 0 0 0 0 0 0 0 0 0 0 0]

	//slice的删除中间元素
	slice = append(copy_slice[:1], copy_slice[2:]...)
	fmt.Println("delect_中间:", slice) //[11111 7 6 5 10 11 12 13 0 0 0 0 0 0 0 0 0 0 0]

	//slice删除两端元素
	fmt.Println("delect_开始:", copy_slice[1:])                 //[7 6 5 10 11 12 13 0 0 0 0 0 0 0 0 0 0 0 0]
	fmt.Println("delect_结束:", copy_slice[:len(copy_slice)-1]) //[11111 7 6 5 10 11 12 13 0 0 0 0 0 0 0 0 0 0 0]

	//练习1.reverse函数在原内存空间将[]int类型的slice反转
	fmt.Println(reverse(arr))
	//练习2.remove函数在原slice中剔除一个
	fmt.Println(remove(arr, 3))

	mSlice := make(Slice, 10, 20)
	mSlice.Append(5)
	fmt.Println(mSlice)

}

type Slice []int

func (A Slice) Append(value int) {
	A1 := append(A, value)
	fmt.Printf("%p\n%p\n", A, A1)

}

//[]表示传递的是切片
func sss(s []int, num int) {
	s[0] = num
}

func reverse(s []int) []int {
	b := []int{}
	for i := len(s); i > 0; i-- {
		b = append(b, s[i-1])
	}
	return b
}

//移除是从0开始的
func remove(s []int, a int) ([]int, error) {
	b := []int{}
	if len(s) < a+1 {
		return []int{}, fmt.Errorf("你错了", s)
	} else {
		b = append(s[:a], s[a+1:]...)
		return b, nil
	}
}
